<script setup lang="ts">
import dayjs from 'dayjs'
import { fetchCancelReasonAndConfigAPI } from '@/apis/fetchCancelReasonAndConfig'
import { useCancelReasonAndConfigStore } from '@/store/cancelReasonAndConfig'
import { useUserInfoStore } from '@/store/userInfo'
import { appointmentAPI } from '@/apis/appointment'

const router = useRouter()
const userInfoStore = useUserInfoStore()
const cancelReasonAndConfigStore = useCancelReasonAndConfigStore()

onLoad(async () => {
  const res = await fetchCancelReasonAndConfigAPI(userInfoStore.userInfo!.token!)
  if (res.data?.code === 1)
    cancelReasonAndConfigStore.setCancelReasonAndConfigData(res.data?.data)
  else
    uni.showToast({ title: res.data?.msg, icon: 'none' })
})

// 是否同意协议
const isAgree = ref(false)
// 表单 ref
const formRef = ref<any>(null)

// 表单数据
const formData = ref({
  name: '',
  gender: '',
  age: '',
  time: '',
  mobile: userInfoStore.userInfo?.mobile || '',
  projects: [] as string[],
  note: '',
})

// 表单校验规则
const rules = {
  name: [
    { required: true, message: '请输入姓名', trigger: ['blur', 'change'] },
  ],
  gender: [
    { required: true, message: '请输入性别', trigger: ['blur', 'change'] },
  ],
  age: [
    { required: true, message: '请输入年龄', trigger: ['blur', 'change'] },
  ],
  time: [
    { required: true, message: '请输入预计到店时间', trigger: ['blur', 'change'] },
  ],
  mobile: [
    { required: true, message: '请输入手机号', trigger: ['blur', 'change'] },
  ],
  projects: [
    {
      required: true,
      transform(value: string[]) {
        return value.join(',')
      },
      message: '请选择预约项目',
      trigger: ['blur', 'change'],
    },
  ],
}

/* ------------------------------- 选择性别 START ------------------------------- */
// 选中的性别 index
const selectedGenderIndex = ref(0)

/**
 * @description 选性别事件
 */
function handleChooseGender(e: any) {
  const index = Number(e.detail.value)
  selectedGenderIndex.value = index
  formData.value.gender = ['男', '女'][index]
}
/* -------------------------------- 选择性别 END -------------------------------- */

/* ------------------------------ 选择到店日期&时间 START ------------------------------ */
// 日历 ref
const calendarRef = ref<any>(null)

const minDate = ref('')
const maxDate = ref('')

// 临时选择的包含日期和时间的数组，[0] -> date，[1] -> time
const tempDateStringList = ref<string[]>([])

// 时间选择器状态
const timePickerSelection = ref<number[]>([])

// 初始化时间选择器默认 state
onMounted(() => {
  const now = dayjs(Date.now())
  timePickerSelection.value[0] = now.hour()
  timePickerSelection.value[1] = now.minute()

  minDate.value = now.format('YYYY-MM-DD')
  maxDate.value = `${now.format('YYYY')}-${now.format('MM')}-${now.format('YYYY') + 9999}`
})

// 显示在 cell 中的 date
const displayedDate = computed(() => {
  if (tempDateStringList.value[0])
    return dayjs(tempDateStringList.value[0]).format('YYYY-MM-DD')
})

// 显示在 cell 中的 time
const displayedTime = computed(() => {
  return tempDateStringList.value[1]
})

/**
 * @description 选择日期事件
 */
function handleChooseDate(e: any) {
  tempDateStringList.value[0] = e.fulldate
  updateTime()
}

/**
 * @description 选择时间事件
 */
function handleChooseTime(e: any) {
  tempDateStringList.value[1] = e.detail.value
  updateTime()
}

// 将时间和日期更新到 formData
function updateTime() {
  if (tempDateStringList.value.length === 2) {
    const dateInstance = dayjs(`${tempDateStringList.value[0]} ${tempDateStringList.value[1]}`, 'YYYY-MM-DD HH:mm')
    formData.value.time = `${dateInstance.format('YYYY-MM-DD HH:mm:ss')}`
  }
}
/* ------------------------------- 选择到店日期&时间 END ------------------------------- */

/* ------------------------------ 选择预约项目 START ------------------------------ */
/**
 * @description 选择预约项目事件
 */
function handleCheckboxChange(e: any) {
  formData.value.projects = e
}
/* ------------------------------- 选择预约项目 END ------------------------------- */
/**
 * @description 表单提交事件
 */
const handleSubmit = useThrottleFn(() => {
  if (!isAgree.value) {
    uni.showToast({ title: '请先阅读并同意《预约协议》', icon: 'none' })
    return
  }

  formRef.value.validate()
    .then(async () => {
      try {
        const res = await appointmentAPI({
          user_name: formData.value.name,
          age: formData.value.age,
          sex: formData.value.gender,
          mobile: formData.value.mobile,
          visit_time: formData.value.time,
          visit_project_ids: formData.value.projects.join(','),
          remark: formData.value.note,
        }, userInfoStore.userInfo!.token!)

        uni.hideLoading()

        if (res.data?.code === 1)
          router.replace('appointmentSuccess')

        else
          uni.showToast({ title: res.data?.msg, icon: 'none' })
      }
      catch (err) {
        uni.showToast({ title: JSON.stringify(err), icon: 'none' })
      }
    })
    .catch((errors: AnyObject[]) => {
      // 表单验证失败
      if (errors.length > 0)
        uni.showToast({ title: errors[0].message, icon: 'none' })
    })
}, 500)

function handleViewProtocol() {
  router.push({
    name: 'protocol',
    params: { type: '预约协议' },
  })
}
</script>

<template>
  <Spacer height="44" />
  <Title>填写预约信息</Title>
  <Spacer height="24" />
  <uv-form ref="formRef" :model="formData" :rules="rules">
    <view class="overflow-hidden rounded-10rpx bg-white">
      <uv-form-item prop="name" label-position="top" :custom-style="{ padding: 0, margin: 0 }">
        <ListCell label="姓名">
          <ListInput v-model="formData.name" placeholder="请输入姓名" />
        </ListCell>
      </uv-form-item>
      <Divider width="623" color="#E6E6E6" />
      <uv-form-item prop="gender" label-position="top" :custom-style="{ padding: 0, margin: 0 }">
        <picker :value="selectedGenderIndex" :range="['男', '女']" @change="handleChooseGender">
          <ListCell label="性别">
            <ListLink :value="formData.gender" placeholder="请选择性别" />
          </ListCell>
        </picker>
      </uv-form-item>
      <Divider width="623" color="#E6E6E6" />
      <uv-form-item prop="age" label-position="top" :custom-style="{ padding: 0, margin: 0 }">
        <ListCell label="年龄">
          <ListInput v-model="formData.age" placeholder="请输入年龄" />
        </ListCell>
      </uv-form-item>
      <Divider width="623" color="#E6E6E6" />
      <uv-form-item prop="time" label-position="top" :custom-style="{ padding: 0, margin: 0 }">
        <ListCell label="预计到店日期" @tap="calendarRef.open()">
          <ListLink :value="displayedDate" placeholder="请选择到店日期" />
        </ListCell>
      </uv-form-item>
      <Divider width="623" color="#E6E6E6" />
      <uv-form-item prop="time" label-position="top" :custom-style="{ padding: 0, margin: 0 }">
        <picker :value="timePickerSelection" mode="time" @change="handleChooseTime">
          <ListCell label="预计到店时间">
            <ListLink :value="displayedTime" placeholder="请选择到店时间" />
          </ListCell>
        </picker>
      </uv-form-item>
      <Divider width="623" color="#E6E6E6" />
      <uv-form-item prop="mobile" label-position="top" :custom-style="{ padding: 0, margin: 0 }">
        <ListCell label="手机号">
          <ListInput v-model="formData.mobile" :maxlength="11" placeholder="请输入手机号" />
        </ListCell>
      </uv-form-item>
      <Divider width="623" color="#E6E6E6" />
      <uv-form-item prop="projects" label-position="top" :custom-style="{ padding: 0, margin: 0 }">
        <ListCell label="预约的项目（多选）" direction="column" :disable-hover-style="true">
          <uv-checkbox-group
            v-model="formData.projects"
            :custom-style="{ display: 'grid', gridTemplateColumns: 'repeat(2, minmax(0, 1fr))', gap: '24rpx' }"
            active-color="#4999F7"
            @change="handleCheckboxChange"
          >
            <uv-checkbox
              v-for="project in cancelReasonAndConfigStore.cancelReasonAndConfigData?.reserve_project"
              :key="project.id"
              :name="project.id.toString()"
              :label="project.reserve_project"
              label-size="28rpx"
              :label-color="formData.projects.includes(project.reserve_project) ? '#000000' : '#848484'"
              shape="circle"
              size="40rpx"
            />
          </uv-checkbox-group>
        </ListCell>
      </uv-form-item>
    </view>
    <Spacer height="24" />
    <view class="overflow-hidden rounded-10rpx bg-white">
      <uv-form-item prop="note" label-position="top" :custom-style="{ padding: 0, margin: 0 }">
        <ListCell label="备注" direction="column" :disable-hover-style="true">
          <textarea
            v-model="formData.note"
            class="text-28rpx text-#333333 leading-40rpx"
            placeholder="请输入备注"
            placeholder-class="text-#848484"
          />
        </ListCell>
      </uv-form-item>
    </view>
    <Spacer height="360" />
  </uv-form>
  <view class="fixed bottom-0 z-10 w-screen bg-#F8F8F8 px-24rpx py-35rpx pb-80rpx x-center">
    <view class="flex items-center" @tap="isAgree = !isAgree">
      <Checkbox :checked="isAgree" />
      <Spacer width="16" />
      <view class="text-24rpx text-#4D4D4D leading-32rpx">
        阅读并同意
        <text class="text-#4999F7" @tap.stop="handleViewProtocol">
          《预约协议》
        </text>
      </view>
    </view>
    <Spacer height="24" />
    <button
      class="h-120rpx w-700rpx flex items-center justify-center rounded-10rpx from-#4999F7 to-#77DAFE bg-gradient-to-r text-36rpx text-white font-medium"
      @tap="handleSubmit"
    >
      立即预约
    </button>
  </view>

  <uv-calendars
    ref="calendarRef" :insert="false" round="20rpx" :start-date="minDate"
    @confirm="handleChooseDate"
  />
</template>

<route lang="yaml">
name: 'appointment'
style:
  navigationBarTitleText: '预约就诊'
</route>
